package com.slmxz.tms.document.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.slmxz.tms.common.base.IBaseEnum;
import com.slmxz.tms.common.component.PrimaryKeyGeneratorService;
import com.slmxz.tms.common.component.RedisUserService;
import com.slmxz.tms.common.constant.SystemConstants;
import com.slmxz.tms.common.enums.BizMessageEnum;
import com.slmxz.tms.common.enums.TableEnum;
import com.slmxz.tms.common.model.Option;
import com.slmxz.tms.core.exception.Asserts;
import com.slmxz.tms.core.exception.BizException;
import com.slmxz.tms.common.result.ResultCode;
import com.slmxz.tms.core.service.DataScopeService;
import com.slmxz.tms.document.enums.TruckTypeEnum;
import com.slmxz.tms.document.mapper.*;
import com.slmxz.tms.document.model.entity.*;
import com.slmxz.tms.document.model.vo.ContractorTruckVO;
import com.slmxz.tms.document.model.vo.TruckVO;
import com.slmxz.tms.document.service.TruckService;
import com.slmxz.tms.system.model.vo.UserInfoVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 车辆信息服务实现类
 * @author sunyao
 * @Date 2024-11-08
 */
@Service
@RequiredArgsConstructor
public class TruckServiceImpl extends ServiceImpl<TruckMapper, Truck> implements TruckService, DataScopeService<Truck> {

    private final ContractorTruckMapper contractorTruckMapper;
    private final ContractorMapper contractorMapper;
    private final DriverMapper driverMapper;
    private final DriverTruckMapper driverTruckMapper;
    /**
    * 获取车辆信息分页列表
    * @return {@link IPage< TruckVO >} 车辆信息分页列表
    */
    @Override
    public IPage<TruckVO> selectTruckPage(IPage<TruckVO> page,TruckVO truck) {
        UserInfoVO user = RedisUserService.currentUser();
        try{
            this.dataScopeHandler(truck);
        }catch (Exception e){
            truck.setScopeNo(user.getScopeNo());
            truck.setDataOperate(SystemConstants.OPERATE_EQUALS);
        }
        truck.setCompanyId(user.getCompanyId());
        List<TruckVO> trucks = this.baseMapper.selectTruckPage(page,truck);
        if(CollectionUtil.isNotEmpty(trucks)){
            trucks.forEach(item -> {
                item.setTruckTypeLabel(IBaseEnum.getLabelByValue(item.getTruckType(), TruckTypeEnum.class));
            });
        }
        return page.setRecords(trucks);
    }

    @Override
    public List<Option<String>> selectOption(TruckVO truck) {
        return this.baseMapper.selectOption(truck);
    }

    /**
     * @param id 车辆信息ID
     * @return
     */
    @Override
    public TruckVO selectTruckDetail(Long id) {
        Truck entity = this.getById(id);
        TruckVO truck = BeanUtil.copyProperties(entity,TruckVO.class);
        //获取关联的承运商信息
        ContractorTruckVO contractorTruckParam = new ContractorTruckVO();
        contractorTruckParam.setTruckId(id);
        List<ContractorTruckVO> contractorTrucks = this.contractorTruckMapper.selectContractorTruck(contractorTruckParam);
        if(CollectionUtil.isNotEmpty(contractorTrucks)){
            ContractorTruckVO contractorTruck = contractorTrucks.get(0);
            truck.setContractorId(contractorTruck.getContractorId());
            truck.setContractorName(contractorTruck.getContractorName());
        }
        QueryWrapper<DriverTruck> driverTruckQuery = new QueryWrapper<>();
        driverTruckQuery.lambda().eq(DriverTruck::getTruckId,id);
        List<DriverTruck> driverTrucks = this.driverTruckMapper.selectList(driverTruckQuery);
        if(CollectionUtil.isNotEmpty(driverTrucks)){
            List<Long> driverIds = driverTrucks.stream().map(DriverTruck::getDriverId).toList();
            truck.setDriverIds(driverIds);
        }
        return truck;
    }
    
    /**
     * 新增车辆信息
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveTruck(TruckVO truck) throws Exception {
        Long truckId = PrimaryKeyGeneratorService.generateId(TableEnum.TABLE_TRUCK);
        truck.setId(truckId);
        //校验选择的承运商数据是否还存在
        long count = this.contractorMapper.selectCount(new QueryWrapper<Contractor>().lambda().eq(Contractor::getId,truck.getContractorId())
                .eq(Contractor::getIsDeleted,0));
        Asserts.fail(count == 0,BizMessageEnum.BIZ0000001);

        ContractorTruck contractorTruck = new ContractorTruck();
        contractorTruck.setContractorId(truck.getContractorId());
        contractorTruck.setTruckId(truckId);
        this.contractorTruckMapper.insert(contractorTruck);
        // 关联司机信息
        if(CollectionUtil.isNotEmpty(truck.getDriverIds())){
            QueryWrapper<Driver> driverQuery = new QueryWrapper<>();
            driverQuery.lambda().in(Driver::getId,truck.getDriverIds()).eq(Driver::getIsDeleted,0);
            long driverCount = this.driverMapper.selectCount(driverQuery);
            Asserts.fail(driverCount != truck.getDriverIds().size(),BizMessageEnum.BIZ0000001);

            List<DriverTruck> driverTrucks = new ArrayList<>();
            for(Long driverId : truck.getDriverIds()){
                DriverTruck driverTruck = new DriverTruck();
                driverTruck.setId(PrimaryKeyGeneratorService.generateId(TableEnum.TABLE_DRIVER_TRUCK));
                driverTruck.setDriverId(driverId);
                driverTruck.setTruckId(truckId);

                driverTrucks.add(driverTruck);
            }
            this.driverTruckMapper.batchInsert(driverTrucks);
        }
        return this.save(truck);
    }
    
    /**
     * 更新车辆信息
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateTruck(TruckVO truck) throws Exception {
        //校验选择的承运商数据是否还存在
        long count = this.contractorMapper.selectCount(new QueryWrapper<Contractor>()
                .lambda().eq(Contractor::getId,truck.getContractorId())
                .eq(Contractor::getIsDeleted,0));
        Asserts.fail(count == 0,BizMessageEnum.BIZ0000001);

        QueryWrapper<ContractorTruck> contractorTruckQuery = new QueryWrapper<>();
        contractorTruckQuery.lambda().eq(ContractorTruck::getTruckId,truck.getId());
        List<ContractorTruck> contractorTrucks = this.contractorTruckMapper.selectList(contractorTruckQuery);
        if(CollectionUtil.isNotEmpty(contractorTrucks)){
            contractorTrucks.forEach(item -> {
                if(item.getContractorId().equals(truck.getContractorId())){
                    //相等则不需要修改
                    return;
                }
                item.setContractorId(truck.getContractorId());
                this.contractorTruckMapper.updateById(item);
            });
        }
        if(CollectionUtil.isNotEmpty(truck.getDriverIds())){
            QueryWrapper<Driver> driverQuery = new QueryWrapper<>();
            driverQuery.lambda().in(Driver::getId,truck.getDriverIds()).eq(Driver::getIsDeleted,0);
            long driverCount = this.driverMapper.selectCount(driverQuery);
            Asserts.fail(driverCount != truck.getDriverIds().size(),BizMessageEnum.BIZ0000001);

            QueryWrapper<DriverTruck> driverTruckQuery = new QueryWrapper<>();
            driverTruckQuery.lambda().eq(DriverTruck::getTruckId,truck.getId());
            List<DriverTruck> driverTrucks = this.driverTruckMapper.selectList(driverTruckQuery);
            if(CollectionUtil.isEmpty(driverTrucks)){
                //之前没有录入过该车辆和司机的绑定关系
                for(Long driverId : truck.getDriverIds()){
                    DriverTruck driverTruck = new DriverTruck();
                    driverTruck.setId(PrimaryKeyGeneratorService.generateId(TableEnum.TABLE_DRIVER_TRUCK));
                    driverTruck.setDriverId(driverId);
                    driverTruck.setTruckId(truck.getId());

                    driverTrucks.add(driverTruck);
                }
                this.driverTruckMapper.batchInsert(driverTrucks);
                //修改车辆自身的信息
                return this.updateById(truck);
            }
            //找出当前车辆之前绑定的司机,但是现在需要删除绑定关系
            List<Long> deleteDrivers = new ArrayList<>();
            for(DriverTruck driverTruck : driverTrucks){
                if(!truck.getDriverIds().contains(driverTruck.getDriverId())){
                    deleteDrivers.add(driverTruck.getDriverId());
                }
            }
            if(CollectionUtil.isNotEmpty(deleteDrivers)){
                this.driverTruckMapper.delete(new QueryWrapper<DriverTruck>().lambda().in(DriverTruck::getDriverId,deleteDrivers)
                        .eq(DriverTruck::getTruckId,truck.getId()));
            }
            //找到新增的司机
            List<DriverTruck> newDrivers = new ArrayList<>();
            List<Long> oldDrivers = driverTrucks.stream().map(DriverTruck::getDriverId).toList();
            for(Long driverId : truck.getDriverIds()){
                if(oldDrivers.contains(driverId)){
                    continue;
                }
                DriverTruck driverTruck = new DriverTruck();
                driverTruck.setId(PrimaryKeyGeneratorService.generateId(TableEnum.TABLE_DRIVER_TRUCK));
                driverTruck.setDriverId(driverId);
                driverTruck.setTruckId(truck.getId());

                newDrivers.add(driverTruck);
            }
            if(CollectionUtil.isNotEmpty(newDrivers)){
                this.driverTruckMapper.batchInsert(newDrivers);
            }
        }
        return this.updateById(truck);
    }
    
    /**
     * 删除车辆信息
     *
     * @param ids 车辆信息ID，多个以英文逗号(,)分割
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteTrucks(String ids) {
        Asserts.fail(StrUtil.isBlank(ids), BizMessageEnum.PARAM_IS_NULL);
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        //删除车辆对应的承运商关系
        QueryWrapper<ContractorTruck> contractorTruckQuery = new QueryWrapper<>();
        contractorTruckQuery.lambda().in(ContractorTruck::getTruckId,idList);
        this.contractorTruckMapper.delete(contractorTruckQuery);
        return this.removeByIds(idList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean activeOrLogout(TruckVO truck) {
        //激活或者注销业务数据
        Asserts.fail(CollectionUtil.isEmpty(truck.getIds()) || truck.getIsDeleted() == null, BizMessageEnum.PARAM_IS_NULL);

        List<Truck>  truckList = new ArrayList<>(truck.getIds().size());
        truck.getIds().forEach(id -> {
            Truck truckParam = new Truck();
            truckParam.setId(id);
            truckParam.setIsDeleted(truck.getIsDeleted());
            truckList.add(truckParam);
        });
        this.updateBatchById(truckList,10);
        return true;
    }

}
